using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Xeralabs.GDESK.Test.GDESK;
using Xeralabs.GDESK.Test.Entities;
using Xeralabs.GDESK.Entities;

namespace Xeralabs.GDESK.Test.User
{
    public partial class Test02Form : Form
    {
        private Test02Factory fixedFactory;

        public Test02Form()
        {
            fixedFactory = new Test02Factory();

            InitializeComponent();
        }

        private void EndTestButton_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void AddKernelButton_Click(object sender, EventArgs e)
        {
            int index = this.kernelList.Items.Add(new Test02Kernel());
            if (((Test02Kernel)this.kernelList.Items[index]).Initialized)
            {
                ((Test02Kernel)this.kernelList.Items[index]).UpdateForm += new Test02Delegate(Test02Kernel_UpdateForm);
            }
            else
                this.kernelList.Items.RemoveAt(index);
        }
        private void RemoveKernelButton_Click(object sender, EventArgs e)
        {
            if (this.kernelList.SelectedIndex != -1)
            {
                ((Test02Kernel)kernelList.SelectedItem).EndSimulation(false);
                ((Test02Kernel)kernelList.SelectedItem).Dispose();
                kernelList.Items.RemoveAt(kernelList.SelectedIndex);
            }
        }

        private void AddEntityButton_Click(object sender, EventArgs e)
        {
            if (inactiveList.SelectedIndex == -1)
            {
                ((Test02Kernel)kernelList.SelectedItem).ActivateEntity(this.fixedFactory.CreateEntity());
            }
            else
            {
                ((Test02Kernel)kernelList.SelectedItem).ActivateEntity((ulong)inactiveList.SelectedItem);
            }
            UpdateEntityList();
            UpdateInactiveList();
        }
        private void RemoveEntityButton_Click(object sender, EventArgs e)
        {
            if ((kernelList.SelectedIndex != -1) && (entityList.SelectedIndex != -1))
            {
                ((Test02Kernel)kernelList.SelectedItem).DeactivateEntity((ulong)entityList.SelectedItem);
                UpdateEntityList();
                UpdateInactiveList();
            }
        }

        private void KillInactiveButton_Click(object sender, EventArgs e)
        {
            if (inactiveList.SelectedIndex != -1)
            {
                fixedFactory.DisposeInactive((ulong)inactiveList.SelectedItem);
            }
            UpdateEntityList();
            UpdateInactiveList();
        }

        private void KernelList_SelectedIndexChanged(object sender, System.EventArgs e)
        {
            if (kernelList.SelectedIndex == -1)
            {
                _removeKernelButton.Enabled = false;
                _addEntityButton.Enabled = false;
                button100.Enabled = false;
                button1000.Enabled = false;
                button10000.Enabled = false;
                button50000.Enabled = false;
                _removeEntityButton.Enabled = false;
                _runButton.Enabled = false;
            }
            else
            {
                _removeKernelButton.Enabled = true;
                _addEntityButton.Enabled = true;
                button100.Enabled = true;
                button1000.Enabled = true;
                button10000.Enabled = true;
                button50000.Enabled = true;
                _runButton.Enabled = true;
                if (((Test02Kernel)kernelList.SelectedItem).IsRunning())
                {
                    _runButton.Text = "Stop";
                    _activityLabel.Text = "ACTIVE";
                    _runButton.Tag = 1;
                }
                else
                {
                    _runButton.Text = "Run";
                    _activityLabel.Text = "INACTIVE";
                    _runButton.Tag = null;
                }
            }
            UpdateEntityList();
            UpdateInactiveList();
            ClearMessaging();
        }

        private void EntityList_SelectedIndexChanged(object sender, System.EventArgs e)
        {
            if (entityList.SelectedIndex == -1)
            {
                _removeEntityButton.Enabled = false;
                _getSenderButton.Enabled = false;
                _getReciverButton.Enabled = false;
            }
            else
            {
                _removeEntityButton.Enabled = true;
                _getSenderButton.Enabled = true;
                _getReciverButton.Enabled = true;
            }
        }

        private void InactiveList_SelectedIndexChanged(object sender, System.EventArgs e)
        {
            if (inactiveList.SelectedIndex == -1)
            {
                _killInactiveButton.Enabled = false;
            }
            else
            {
                _killInactiveButton.Enabled = true;
            }
        }

        private void UpdateEntityList()
        {
            int old = entityList.SelectedIndex;
            entityList.Items.Clear();

            if (kernelList.SelectedIndex != -1)
            {
                ulong[] guidArray = ((Test02Kernel)kernelList.Items[kernelList.SelectedIndex]).GetGUIDList();

                for (int a = 0; a < guidArray.Length; a++)
                {
                    entityList.Items.Add(guidArray[a]);
                }

                if (old >= entityList.Items.Count)
                    old = entityList.Items.Count - 1;

                entityList.SelectedIndex = old;
                if (entityList.SelectedIndex == -1)
                    _removeEntityButton.Enabled = false;
            }
        }

        private void UpdateInactiveList()
        {
            int old = inactiveList.SelectedIndex;

            inactiveList.Items.Clear();

            ulong[] guidArray = fixedFactory.GetInactiveList();

            for (int a = 0; a < guidArray.Length; a++)
            {
                inactiveList.Items.Add(guidArray[a]);
            }

            if (old >= inactiveList.Items.Count)
                old = inactiveList.Items.Count - 1;

            inactiveList.SelectedIndex = old;
            if (inactiveList.SelectedIndex == -1)
                _killInactiveButton.Enabled = false;

        }

        private void SenderTextBox_TextChanged(object sender, EventArgs e)
        {
            ulong tmp1, tmp2;

            if (ulong.TryParse(_senderTextBox.Text, out tmp1) && ulong.TryParse(_reciverTextBox.Text, out tmp2))
            {
                if (this.entityList.Items.Contains(tmp1) && this.entityList.Items.Contains(tmp2))
                {
                    this._sendMessageButton.Enabled = true;
                    return;
                }
            }
            this._sendMessageButton.Enabled = false;
        }

        private void ReciverTextBox_TextChanged(object sender, EventArgs e)
        {
            ulong tmp1, tmp2;

            if (ulong.TryParse(_senderTextBox.Text, out tmp1) && ulong.TryParse(_reciverTextBox.Text, out tmp2))
            {
                if (this.entityList.Items.Contains(tmp1) && this.entityList.Items.Contains(tmp2))
                {
                    this._sendMessageButton.Enabled = true;
                    return;
                }
            }
            this._sendMessageButton.Enabled = false;

        }

        private void GetSenderButton_Click(object sender, EventArgs e)
        {
            if (this.entityList.SelectedIndex != -1)
            {
                _senderTextBox.Text = ((ulong)this.entityList.SelectedItem).ToString();
            }
            else
                _senderTextBox.Text = "";
        }

        private void GetReciverButton_Click(object sender, EventArgs e)
        {
            if (this.entityList.SelectedIndex != -1)
            {
                _reciverTextBox.Text = ((ulong)this.entityList.SelectedItem).ToString();
            }
            else
                _reciverTextBox.Text = "";
        }

        private void SendMessageButton_Click(object sender, EventArgs e)
        {
            ulong tmp1, tmp2;

            if (ulong.TryParse(_senderTextBox.Text, out tmp1) && ulong.TryParse(_reciverTextBox.Text, out tmp2))
            {
                if (kernelList.SelectedIndex != -1)
                {
                    ((Test02Entity)((Test02Kernel)kernelList.SelectedItem).GetEntity(tmp1)).Send(tmp2, (double)this.numericUpDown1.Value, null);
                }
            }
        }

        private void ClearMessaging()
        {
            this._senderTextBox.Text = "";
            this._reciverTextBox.Text = "";
            this._getSenderButton.Enabled = false;
            this._getReciverButton.Enabled = false;
            this._sendMessageButton.Enabled = false;
        }

        private void RunButton_Click(object sender, EventArgs e)
        {
            if (kernelList.SelectedIndex != -1)
            {
                if (_runButton.Tag == null)
                {
                    ((Test02Kernel)kernelList.SelectedItem).RunSimulation();
                    _runButton.Text = "Stop";
                    _activityLabel.Text = "ACTIVE";
                    _runButton.Tag = 1;
                }
                else if (_runButton.Tag != null)
                {
                    //Stop
                    ((Test02Kernel)kernelList.SelectedItem).StopSimulation(false);
                    _runButton.Text = "Run";
                    _activityLabel.Text = "INACTIVE";
                    _runButton.Tag = null;
                }
            }
        }

        void Test02Kernel_UpdateForm(ulong sender, ulong reciver, double timeMark)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Test02Delegate(Test02Kernel_UpdateForm), sender, reciver, timeMark);
            }
            else
            {
                UpdateSenderLabelMessage(sender);

                UpdateReciverLabelMessage(reciver);

                UpdateTimeMarkLabelMessage(timeMark);
            }
        }

        private delegate void UpdateDouble(double value);
        private void UpdateTimeMarkLabelMessage(double timeMark)
        {
            if (labelTime.InvokeRequired)
            {
                labelTime.Invoke(new UpdateDouble(UpdateTimeMarkLabelMessage), timeMark);
            }
            else
            {
                labelTime.Text = timeMark.ToString();
            }
        }
        private delegate void UpdateULong(ulong value);
        private void UpdateReciverLabelMessage(ulong reciver)
        {
            if (labelReciver.InvokeRequired)
            {
                labelReciver.Invoke(new UpdateULong(UpdateReciverLabelMessage), reciver);
            }
            else
            {
                labelReciver.Text = reciver.ToString();
            }
        }

        private void UpdateSenderLabelMessage(ulong sender)
        {
            if (labelSender.InvokeRequired)
            {
                labelSender.Invoke(new UpdateULong(UpdateSenderLabelMessage), sender);
            }
            else
            {
                labelSender.Text = sender.ToString();
            }
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            foreach (Test02Kernel kern in this.kernelList.Items)
            {
                ulong[] guids = kern.GetGUIDList();
                if (guids.Length > 0)
                {
                    for (int a = 0; a < guids.Length; a++)
                    {
                        kern.DeactivateEntity(guids[a]);
                        fixedFactory.DisposeInactive(guids[a]);
                    }
                }
                kern.EndSimulation(false);
                kern.Dispose();
            }

            kernelList.Items.Clear();

            this.Owner.Show();

            base.OnClosing(e);
        }

        private void button100_Click(object sender, EventArgs e)
        {
            if (kernelList.SelectedIndex != -1)
            {
                for (int a = 0; a < 100; a++)
                {
                    ((Test02Kernel)kernelList.SelectedItem).ActivateEntity(this.fixedFactory.CreateEntity());
                }
            }
            UpdateEntityList();
            UpdateInactiveList();
        }

        private void button1000_Click(object sender, EventArgs e)
        {
            if (kernelList.SelectedIndex != -1)
            {
                for (int a = 0; a < 1000; a++)
                {
                    ((Test02Kernel)kernelList.SelectedItem).ActivateEntity(this.fixedFactory.CreateEntity());
                }
            }
            UpdateEntityList();
            UpdateInactiveList();
        }

        private void button10000_Click(object sender, EventArgs e)
        {
            if (kernelList.SelectedIndex != -1)
            {
                for (int a = 0; a < 10000; a++)
                {
                    ((Test02Kernel)kernelList.SelectedItem).ActivateEntity(this.fixedFactory.CreateEntity());
                }
            }
            UpdateEntityList();
            UpdateInactiveList();
        }

        private void button50000_Click(object sender, EventArgs e)
        {
            if (kernelList.SelectedIndex != -1)
            {
                for (int a = 0; a < 1000000; a++)
                {
                    ((Test02Kernel)kernelList.SelectedItem).ActivateEntity(this.fixedFactory.CreateEntity());
                }
            }
            UpdateEntityList();
            UpdateInactiveList();
        }
    }
}